package com.baidu.ueditor.hunter;

import com.baidu.ueditor.ConfigManager;
import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.*;
import com.baidu.ueditor.entity.FileEntity;
import com.baidu.ueditor.tools.SqliteUtils;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class FileManager implements IFileManager{

    private String dir = null;
    private String rootPath = null;
    private String[] allowFiles = null;
    private int count = 0;

    private String contextPath;


    @Override
    public void init(Map<String, Object> conf, String contextPath) {
        this.rootPath = (String) conf.get("rootPath");
        this.dir = this.rootPath + conf.get("dir");
        this.allowFiles = getAllowFiles(conf.get("allowFiles"));
        this.count = (Integer) conf.get("count");
        this.contextPath = contextPath;
    }

    @Override
    public State listFile(int index) {

        File dir = new File(this.dir);
        State state = null;

        if (!dir.exists()) {
            return new BaseState(false, AppInfo.NOT_EXIST);
        }

        if (!dir.isDirectory()) {
            return new BaseState(false, AppInfo.NOT_DIRECTORY);
        }

        Collection<File> list = FileUtils.listFiles(dir, this.allowFiles, true);

        if (index < 0 || index > list.size()) {
            state = new MultiState(true);
        } else {
            Object[] fileList = Arrays.copyOfRange(list.toArray(), index, index + this.count);
            state = this.getState(fileList);
        }

        state.putInfo("start", index);
        state.putInfo("total", list.size());

        return state;

    }

    private State getState(Object[] files) {

        MultiState state = new MultiState(true);
        BaseState fileState = null;

        File file = null;

        for (Object obj : files) {
            if (obj == null) {
                break;
            }
            file = (File) obj;
            fileState = new BaseState(true);
            String url = PathFormat.format(this.getPath(file));

            if (checkAttachment(FileType.getSuffixByFilename(file.getName()), contextPath)) {
                String saveName = file.getName();
                String tableName = url.replace(saveName, "");
                tableName = tableName.substring(0, tableName.lastIndexOf("/"));
                tableName = tableName.substring(tableName.lastIndexOf("/") + 1);
                FileEntity entity = SqliteUtils.getOne(tableName, saveName);

                if (entity != null) {
                    fileState.putInfo("original", entity.getUploadName());
                }

            }


            fileState.putInfo("url", url);
            state.addState(fileState);
        }

        return state;

    }

    private static List<String> attachmentAllowFiles;

    public static boolean checkAttachment(String suffix, String contextPath) {
        suffix = suffix.replace(".", "");
        String suffixLowerCase = suffix.toLowerCase();
        String suffixUperCase = suffix.toUpperCase();
        if (attachmentAllowFiles == null) {
            ConfigManager configManager = ConfigManager.getInstance(contextPath);
            Map<String, Object> config = configManager.getConfig(ActionMap.LIST_FILE);
            String[] data = getAllowFiles(config.get("allowFiles"));
            attachmentAllowFiles = Arrays.asList(data);
        }

        if (attachmentAllowFiles.contains(suffixLowerCase) || attachmentAllowFiles.contains(suffixUperCase)) {
            return true;
        }
        return false;
    }

    private String getPath(File file) {
        String path = file.getPath();
        path = path.replaceAll("\\\\", "/");
        return path.replace(this.rootPath, "");

    }

    private static String[] getAllowFiles(Object fileExt) {

        String[] exts = null;
        String ext = null;

        if (fileExt == null) {
            return new String[0];
        }

        exts = (String[]) fileExt;

        for (int i = 0, len = exts.length; i < len; i++) {

            ext = exts[i];
            exts[i] = ext.replace(".", "");

        }

        return exts;

    }

}
